-
-
Notifications
You must be signed in to change notification settings - Fork 293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide generics for Image class #254
base: master
Are you sure you want to change the base?
Provide generics for Image class #254
Conversation
src/types/types.ts
Outdated
/** | ||
* Represents the format of a file object data with the additional data. | ||
*/ | ||
export type FileObjectData<AdditionalData = {}> = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this type is not reused below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it was initially defined to be used to defined parameters types of member functions. But it can be used in the interfaces if you would like to.
src/index.ts
Outdated
|
||
/** | ||
* UI module instance | ||
*/ | ||
private ui: Ui; | ||
private ui: Ui<CustomActions, AdditionalUploadResponse>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to pass ImageToolData<CustomActions, AdditionalUploadResponse>
because UI should not depend on AdditionalUploadResponse, it depends on data format instead since it may be used for rendering
src/index.ts
Outdated
this.image = data.file; | ||
|
||
this._data.caption = data.caption || ''; | ||
this.ui.fillCaption(this._data.caption); | ||
|
||
ImageTool.tunes.forEach(({ name: tune }) => { | ||
const value = typeof data[tune as keyof ImageToolData] !== 'undefined' ? data[tune as keyof ImageToolData] === true || data[tune as keyof ImageToolData] === 'true' : false; | ||
const value = typeof data[tune as keyof ImageToolData<CustomActions, AdditionalUploadResponse>] !== 'undefined' ? data[tune as keyof ImageToolData<CustomActions, AdditionalUploadResponse>] === true || data[tune as keyof ImageToolData<CustomActions, AdditionalUploadResponse>] === 'true' : false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this line is too long and hard to read. Can we do something with it?
src/index.ts
Outdated
|
||
|
||
type ImageToolConstructorOptions = BlockToolConstructorOptions<ImageToolData, ImageConfig> | ||
type ImageToolConstructorOptions< CustomActions = {},AdditionalUploadResponse = {}> = BlockToolConstructorOptions<ImageToolData<CustomActions, AdditionalUploadResponse>, ImageConfig> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type ImageToolConstructorOptions< CustomActions = {},AdditionalUploadResponse = {}> = BlockToolConstructorOptions<ImageToolData<CustomActions, AdditionalUploadResponse>, ImageConfig> | |
type ImageToolConstructorOptions<CustomActions = {}, AdditionalUploadResponse = {}> = BlockToolConstructorOptions<ImageToolData<CustomActions, AdditionalUploadResponse>, ImageConfig> |
src/index.ts
Outdated
|
||
export default class ImageTool implements BlockTool { | ||
export default class ImageTool<CustomActions = {} ,AdditionalUploadResponse = {}> implements BlockTool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
export default class ImageTool<CustomActions = {} ,AdditionalUploadResponse = {}> implements BlockTool { | |
export default class ImageTool<CustomActions = {}, AdditionalUploadResponse = {}> implements BlockTool { |
src/utils/isPromise.ts
Outdated
@@ -5,6 +5,6 @@ import type { UploadResponseFormat } from '../types/types'; | |||
* @param object - object to check | |||
* @returns | |||
*/ | |||
export default function isPromise(object: Promise<UploadResponseFormat>): object is Promise<UploadResponseFormat> { | |||
export default function isPromise<AdditionalUploadResponse>(object: Promise<UploadResponseFormat<AdditionalUploadResponse>>): object is Promise<UploadResponseFormat<AdditionalUploadResponse>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isPromise
is a util, so it should not depend on UploadResponseFormat
and AdditionalUploadResponse
.
Problem
The current design of the
Image
class doesn't make it easily extendable so that users can define their actions and additional fields in the upload response. This also limits class extensions for use cases where custom data and actions must be implemented.Cause
The
Image
class was first designed with types fixed for the actions and upload response data, which is a very concrete design, and it limited the flexibility with different kinds of requirements. The approach taken in designing thus becomes relatively narrow and does not allow an extension of the user's custom properties during the creation ofImage
object.Solution
Generic types should be used to re-implement the
Image
class to fix this problem. The definition of the class should change into classImageTool<CustomActions = {}, AdditionalUploadResponse = {}>
, such that while the object of it is created, users can provide their custom actions and additional upload response types. This makes theImage
class flexible and more usable and leaves the ability to respond to almost any scenario and requirements.